package cn.intellijboy.gradle.plugin.task;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.intellijboy.gradle.plugin.model.DependencyModel;
import cn.intellijboy.gradle.plugin.model.GradleBuildModel;
import cn.intellijboy.gradle.plugin.task.render.XingzheDependencyGraphsRenderer;
import lombok.Setter;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.diagnostics.internal.ConfigurationDetails;
import org.gradle.api.tasks.diagnostics.internal.graph.nodes.RenderableModuleResult;
import org.gradle.api.tasks.options.Option;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 依赖解析任务
 * 获取在线、项目、本地依赖，并且可以指定获取所有或指定的依赖对象，支持获取一层或整棵依赖树
 * <p>
 * 任务名称：analyzeDependency
 * 任务分组：xingzhe
 * 任务入参：--configuration=[compileClasspath, runtimeClasspath] --level=[first,full] --format=[yaml,json]
 * 输出参数：--output=[console,file location]
 */
public class AnalyzeDependencyTask extends AbstractDependencyAnalyzeTask {


    @Setter
    private String level = "full";
    @Setter
    private String format = "yaml";

    @Input
    @Optional
    @Option(option = "level", description = "依赖层级：first（仅直接依赖）或 full（完整依赖树）")
    public String getLevel() {
        return level;
    }

    @Input
    @Optional
    @Option(option = "format", description = "输出格式：yaml 或 json")
    public String getFormat() {
        return format;
    }

    @TaskAction
    public void analyze() {
        GradleBuildModel gradleBuildModel = buildModelCache.get();
        for (ConfigurationDetails configurationModel : gradleBuildModel.configurations()) {
            if (isIgnoreDependencyAnalyze(configurationModel)) {
                continue;
            }
            boolean canBeResolved = configurationModel.isCanBeResolved();
            getLogger().warn("正在解析配置类：" + configurationModel.getName() + " 是否可解析：" + canBeResolved);
            XingzheDependencyGraphsRenderer dependencyGraphsRenderer = new XingzheDependencyGraphsRenderer();
            if (canBeResolved) {
                java.util.Optional.ofNullable(configurationModel.getResolutionResultRoot()).map(Provider::get).ifPresent(root -> {
                    dependencyGraphsRenderer.render(new RenderableModuleResult(root));
                });
            } else {
                dependencyGraphsRenderer.render(configurationModel.getUnresolvableResult());
            }
            // jsonLogPrint(dependencyModels);
            Set<DependencyModel> dependencyModels = dependencyGraphsRenderer.getCollectDependencies();
            // 使用hutool树工具类转换为树形结构
            List<Tree<String>> tree = TreeUtil.build(new ArrayList<>(dependencyModels), null, (dependencyModel, treeNode) -> {
                treeNode.setId(dependencyModel.getId());
                treeNode.setParentId(dependencyModel.getParentId());
                treeNode.putExtra("group", dependencyModel.getGroup());
                treeNode.setName(dependencyModel.getName());
                treeNode.putExtra("version", dependencyModel.getVersion());
            });
            // 打印树形结构
            java.util.Optional.ofNullable(tree).ifPresent(trees -> trees.forEach(t -> t.walk(System.out::println)));
        }

    }

    /**
     * 是否忽略依赖解析
     *
     * @param configurationModel 配置模型
     * @return 是否忽略
     */
    private boolean isIgnoreDependencyAnalyze(ConfigurationDetails configurationModel) {
        String configuration = getConfiguration();
        return configuration != null && !configuration.equals(configurationModel.getName());
    }


}

